/**
 *	@file	telseq_revenge.c
 *	@brief	再戦トレーナー　会話データ抽選＆再生
 *	@author	Miyuki Iwasawa
 *	@date	09.02.06
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/buflen.h"
#include "system/pm_rtc.h"
#include "battle/trtype_def.h"
#include "gflib/touchpanel.h"
#include "field/eventflag.h"
#include "field/evwkdef.h"
#include "field/syswork.h"
#include "field/encount_dat.h"
#include "field/enc_tbl_change_def.h"
#include "field/zonedata.h"
#include "fielddata/script/saveflag.h"
#include "fielddata/maptable/zone_id.h"
#include "battle/battle_common.h"
#include "poketool/tr_tool.h"
#include "itemtool/itemsym.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_pg_tel.h"

#include "../pm_tel.h"
#include "tel/pmtel_def.h"
#include "tel/pmtel_datman.h"
#include "tel/pmtel_dat_def.h"
#include "tel/pmtel_dat_greet.h"
#include "../pmtel_seq.h"
#include "telseq_play.h"


//------------------------------------------------------------------
/**
 * @brief	ゾーン毎のエンカウントデータの読み込み
 * @param	zone_id		ゾーンIDの指定
 * @param	event_data	EVENT_DATA構造体へのポインタ
 *
 * ホントはfield/eventdata.hをインクルードするべきだけど、
 * そうするとFIELDSYS_WORK他が参照できないといけなくなるので特別に直接extern
 */
//------------------------------------------------------------------
extern void EventData_LoadEncountData(GS_ENCOUNT_DATA *enc_data, int zone_id);

///抽選テーブルデータテーブルサイズ
#define SLIST_CALL_IDX	(0)
#define SLIST_CALL_MAX	(8)
#define SLIST_RECEIVE_IDX	(SLIST_CALL_MAX)
#define SLIST_RECEIVE_MAX	(8)
#define SLIST_BLOCK_NUM	(SLIST_CALL_MAX+SLIST_RECEIVE_MAX)

//会話データ抽選テーブル
extern const TELD_SELECT PMTelDat_SelectTbl[];

static u16 playl_TalkSelect(PMTEL_DATA_MAN* man,TELD_SELECT *list,int max);
static BOOL chk_per(u8 per);
static BOOL stblchk_per(PMTEL_DATA_MAN* man,TELD_SELECT* ps);
static BOOL stblchk_evoff(PMTEL_DATA_MAN* man,TELD_SELECT* ps);
static BOOL stblchk_day(PMTEL_DATA_MAN* man,TELD_SELECT* ps);
static BOOL stblchk_revenge(PMTEL_DATA_MAN* man,TELD_SELECT* ps);
static BOOL stblchk_item(PMTEL_DATA_MAN* man,TELD_SELECT* ps);
static BOOL stblchk_mushi(PMTEL_DATA_MAN* man,TELD_SELECT* ps);
static BOOL stblchk_radio(PMTEL_DATA_MAN* man,TELD_SELECT* ps);

/*
 *	@brief	電話　再戦タイプの会話抽選
 */
u16 PMTelPlayL_Revenge(PMTEL_DATA_MAN* man,PMTEL_TALK_WORK* twk)
{
	TELD_SELECT* ps,*list;

	twk->seq_code = TEL_SEQ_SIMPLE;

	IWASAWA_PRINT("PlayL_Revenge %d Search\n",twk->id);
	list = (TELD_SELECT*)&PMTelDat_SelectTbl[twk->id*SLIST_BLOCK_NUM];

	//ノーマル着信
	if(twk->is_receive){
		return playl_TalkSelect(man,&list[SLIST_RECEIVE_IDX],SLIST_RECEIVE_MAX);
	}

	//同一マップにいるか？
	if(twk->pbk->map_id == man->zone_id){
		IWASAWA_PRINT("PlayL_Revenge NETalk %d\n",twk->pbk->netalk_id);
		return twk->pbk->netalk_id;
	}
	//ノーマル発信
	return playl_TalkSelect(man,&list[SLIST_CALL_IDX],SLIST_CALL_MAX);
}

/**
 *	@brief	抽選テーブルのhit判定
 */
static u16 playl_TalkSelect(PMTEL_DATA_MAN* man,TELD_SELECT *list,int max)
{
	PMTEL_TALK_WORK* twk = &man->twk;

	TELD_SELECT* ps,*last;
	int ct,flag;

	flag = 0;
	last = list;
	for(ps = list,ct = 0;ct < max;ct++){
		IWASAWA_PRINT(" search %d per:%d, type:%d, seq_code:%d, seq_no:%d\n",ct,ps->per,ps->type,ps->seq_code,ps->seq_no);
		if(	ps->type == TEL_SELTYP_END ||
			ps->type == TEL_SELTYP_PROG){
			break;
		}
		//条件hitチェック
		switch(ps->type){
		case TEL_SELTYP_EVOFF:
			flag=stblchk_evoff(man,ps);
			break;
		case TEL_SELTYP_REVENGE:
			flag = stblchk_revenge(man,ps);
			break;
		case TEL_SELTYP_ITEM:
			flag = stblchk_item(man,ps);
			break;
		case TEL_SELTYP_DAY:
			flag = stblchk_day(man,ps);
			break;
		case TEL_SELTYP_MUSHI:
			flag = stblchk_mushi(man,ps);
			break;
		case TEL_SELTYP_RADIO:
			flag = stblchk_radio(man,ps);
			break;
		case TEL_SELTYP_ZUKAN:
		case TEL_SELTYP_PER:
		default:
			flag = stblchk_per(man,ps);
			break;
		}
		if(flag){
			twk->seq_code = ps->seq_code;
			return ps->seq_no;
		}
		last = ps++;
	}
	//一番最後にHITしたデータを無条件採用
	if(last->type == TEL_SELTYP_END || last->type == TEL_SELTYP_PROG){
		twk->seq_code = TEL_SEQ_SIMPLE;
		return TEL_TK_DUMMY;
	}else{
		twk->seq_code = last->seq_code;
		return last->seq_no;
	}
}

static BOOL chk_per(u8 per)
{
	int r1;
	u16 rand;

	//ちょっと加工
	r1 = (gf_mtRand()^gf_mtRand());
	rand = ((r1&0xFFFF) ^ (r1>>8));
	rand = rand % 100;

	if(rand <= per){
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	抽選タイプ　確率チェック
 */
static BOOL stblchk_per(PMTEL_DATA_MAN* man,TELD_SELECT* ps)
{
	PMTEL_TALK_WORK* twk = &man->twk;

	return chk_per(ps->per);
}

/**
 *	@brief	抽選タイプ　再戦/アイテムイベント発動中はHITしない
 */
static BOOL stblchk_evoff(PMTEL_DATA_MAN* man,TELD_SELECT* ps)
{
	PMTEL_TALK_WORK* twk = &man->twk;

	//再戦フラグチェック
	if(PMTelSv_RevengeFlagGet(man->tel_sv,twk->id)){
		return FALSE;
	}
	if(PMTelSv_ItemEvDataGet(man->tel_sv,twk->id) != ITEM_DUMMY_DATA){
		return FALSE;
	}
	//再戦予約電話の場合、ラジオ塔占拠イベントクリアまではhitさせない
	if((!EventWork_CheckEventFlag(man->ev_sv,FE_T25_RADIOSENKYO_END)) && (ps->seq_code == TEL_SEQ_SIMPLE)){
		const TELD_SEQ_SIMPLE* dat = PMTel_GetSimpleTalkData(ps->seq_no);
		if(dat->flag_type == TEL_FLAG_REVENGE){
			return FALSE;
		}
	}

	return chk_per(ps->per);
}

/**
 *	@brief	抽選タイプ　指定した曜日とタイムゾーン以外抽選されない
 */
static BOOL stblchk_day(PMTEL_DATA_MAN* man,TELD_SELECT* ps)
{
	PMTEL_TALK_WORK* wk = &man->twk;

	//ラジオ塔占拠イベントクリアまではhitさせない
	if(!EventWork_CheckEventFlag(man->ev_sv,FE_T25_RADIOSENKYO_END)){
		return FALSE;
	}

	if( (wk->rtc_date.week != wk->pbk->week) ||
		(wk->time_zone != wk->pbk->time)){
		return FALSE;
	}
	return chk_per(ps->per);
}

/**
 *	@brief	抽選タイプ　再戦フラグON
 */
static BOOL stblchk_revenge(PMTEL_DATA_MAN* man,TELD_SELECT* ps)
{
	PMTEL_TALK_WORK* twk = &man->twk;

	//ラジオ塔占拠イベントクリアまではhitさせない
	if(!EventWork_CheckEventFlag(man->ev_sv,FE_T25_RADIOSENKYO_END)){
		return FALSE;
	}
	//自然公園にいるトレーナーで虫取り大会最中ならスルー
	if(twk->pbk->map_id == ZONE_ID_D22R0101){
		if(SysFlag_MushitoriCheck(man->ev_sv)){
			return FALSE;
		}
	}
	//再戦フラグチェック
	if(!PMTelSv_RevengeFlagGet(man->tel_sv,twk->id)){
		return FALSE;
	}
	return chk_per(ps->per);
}

/**
 *	@brief	抽選タイプ　アイテムフラグON
 */
static BOOL stblchk_item(PMTEL_DATA_MAN* man,TELD_SELECT* ps)
{
	PMTEL_TALK_WORK* twk = &man->twk;

	//自然公園にいるトレーナーで虫取り大会最中ならスルー
	if(twk->pbk->map_id == ZONE_ID_D22R0101){
		if(SysFlag_MushitoriCheck(man->ev_sv)){
			return FALSE;
		}
	}
	//アイテムフラグチェック
	if(PMTelSv_ItemEvDataGet(man->tel_sv,twk->id) == ITEM_DUMMY_DATA){
		return FALSE;
	}
	return chk_per(ps->per);
}

/**
 *	@brief	抽選タイプ　虫取り大会の開催日のみ有効
 */
static BOOL stblchk_mushi(PMTEL_DATA_MAN* man,TELD_SELECT* ps)
{
	PMTEL_TALK_WORK* wk = &man->twk;

	if(	wk->rtc_date.week == RTC_WEEK_TUESDAY ||
		wk->rtc_date.week == RTC_WEEK_THURSDAY ||
		wk->rtc_date.week == RTC_WEEK_SATURDAY){

		return chk_per(ps->per);
	}
	return FALSE;
}

/**
 *	@brief	抽選タイプ　ラジオ塔占拠中のみ有効
 */
static BOOL stblchk_radio(PMTEL_DATA_MAN* man,TELD_SELECT* ps)
{
	PMTEL_TALK_WORK* wk = &man->twk;

	if(SysWork_CheckDuaringTheRadioTowerEvent(man->ev_sv)){
		return chk_per(ps->per);
	}
	return FALSE;
}

/**
 *	@brief	指定ゾーンでエンカウントするポケモンNoを返す
 */
static u16 sub_GetEncountMonsNo(u16 zone_id,u16 tr_type,u8 time_zone)
{
	GS_ENCOUNT_DATA enc_data;
	u16* tbl;

	if(!ZoneData_GetEncountFlag(zone_id)) {
		return MONSNO_KORATTA;	//ダミー
	}
	EventData_LoadEncountData(&enc_data, zone_id);

	if(tr_type == TRTYPE_FISHING){
		if(time_zone == TIMEZONE_GS_NIGHT){
			enc_data.EncFish2[GD_NIGHT_ENC].MonsterNo = enc_data.FishingNightPoke;
		}
		return enc_data.EncFish2[gf_rand()%ENC_MONS_NUM_FISH].MonsterNo;
	}else{
		switch(time_zone){
		case TIMEZONE_GS_NOON:
			tbl = enc_data.GrndPokeD;
			break;
		case TIMEZONE_GS_NIGHT:
			tbl = enc_data.GrndPokeN;
			break;
		case TIMEZONE_GS_MORNING:
		default:
			tbl = enc_data.GrndPokeM;
			break;
		}
		return tbl[gf_rand()%ENC_MONS_NUM_NORMAL];
	}
}

/**
 *	@brief	指定トレーナーの手持ちポケモンNoを返す
 */
static u16 sub_GetTrainerMonsNo(u16 tr_id,int heapID)
{
	int i;
	TRAINER_DATA	td;
	u16 poke[POKEMON_TEMOTI_MAX];
	void* buf;

	TT_TrainerDataGet(tr_id,&td);

	buf=sys_AllocMemory(heapID,sizeof(POKEDATA_TYPE_MULTI)*POKEMON_TEMOTI_MAX);
	MI_CpuClear8(buf,sizeof(POKEDATA_TYPE_MULTI)*POKEMON_TEMOTI_MAX);
	TT_TrainerPokeDataGet(tr_id,buf);

	switch(td.data_type){
	case DATATYPE_NORMAL:
		{
			POKEDATA_TYPE_NORMAL* pd = (POKEDATA_TYPE_NORMAL*)buf;
			for(i = 0;i < td.poke_count;i++){
				poke[i] = pd[i].monsno;
			}
		}
		break;
	case DATATYPE_WAZA:
		{
			POKEDATA_TYPE_WAZA* pd = (POKEDATA_TYPE_WAZA*)buf;
			for(i = 0;i < td.poke_count;i++){
				poke[i] = pd[i].monsno;
			}
		}
		break;
	case DATATYPE_ITEM:
		{
			POKEDATA_TYPE_ITEM* pd = (POKEDATA_TYPE_ITEM*)buf;
			for(i = 0;i < td.poke_count;i++){
				poke[i] = pd[i].monsno;
			}
		}
		break;
	case DATATYPE_MULTI:
		{
			POKEDATA_TYPE_MULTI* pd = (POKEDATA_TYPE_MULTI*)buf;
			for(i = 0;i < td.poke_count;i++){
				poke[i] = pd[i].monsno;
			}
		}
		break;
	default:	//ここにはこないはずだが
		sys_FreeMemoryEz(buf);
		return MONSNO_KORATTA;
	}
	sys_FreeMemoryEz(buf);

	return poke[gf_rand()%td.poke_count];
}

/**
 *	@brief	再戦タイプの日常会話シーケンス
 */
int PMTelSeq_TypeRevengeDayTalk(PMTEL_DATA_MAN* man)
{
	PMTEL_TALK_WORK *wk = &man->twk;
	switch(wk->seq){
	case 0:
		//タグ展開処理
		PMTel_TagSpreadCommon(man);

		//フラグ処理
		PMTel_SimpleFlagSet(man,PMTel_GetSimpleTalkData(wk->seq_no));

		//トレーナーがいるマップにいるポケモンとトレーナーの手持ちポケモンをタグ展開
		WORDSET_RegisterMonsName( man->wset,WORDSET_TEL_LOCAL_BUF,
			sub_GetTrainerMonsNo(wk->pbk->tr_id,man->heapID));
		WORDSET_RegisterMonsName( man->wset,WORDSET_TEL_LOCAL_BUF+1,
			sub_GetEncountMonsNo(wk->pbk->map_id,wk->pbk->tr_type,wk->time_zone));

		//挨拶データ再生チェック
		if(wk->pbk->greet_idx == TEL_GREET_NONE){
			++wk->seq;
		}
		break;
	case 1:
		//挨拶描画
		if(!PMTelSubSeq_GreetingMsgPlay(man)){
			return FALSE;
		}
		break;
	case 2:
		{	//本文描画
			const TELD_SEQ_SIMPLE* dat = PMTel_GetSimpleTalkData(wk->seq_no);
			PMTel_MsgPrintGmmSex(man,man->m_person,dat->msg[0],dat->msg[1]);
		}
		break;
	default:
		if(!PMTel_MsgPrintWait(man)) return FALSE;
		MSGMAN_Delete(man->m_person);
		return TRUE;
	}
	++wk->seq;
	return FALSE;
}

/**
 *	@brief	再戦タイプの情報電話ランダム11
 */
int PMTelSeq_TypeRevengeRnd11Talk(PMTEL_DATA_MAN* man)
{
	PMTEL_TALK_WORK *wk = &man->twk;
	switch(wk->seq){
	case 0:
		//タグ展開処理
		PMTel_TagSpreadCommon(man);

		//フラグ処理
		PMTel_SimpleFlagSet(man,PMTel_GetSimpleTalkData(wk->seq_no));

		//挨拶データ再生チェック
		if(wk->pbk->greet_idx == TEL_GREET_NONE){
			++wk->seq;
		}
		break;
	case 1:
		//挨拶描画
		if(!PMTelSubSeq_GreetingMsgPlay(man)){
			return FALSE;
		}
		break;
	case 2:
		{	//本文描画
			u8 rnd = gf_rand()%11;
			const TELD_SEQ_SIMPLE* dat = PMTel_GetSimpleTalkData(wk->seq_no);
			if(dat->msg[0] == dat->msg[1]){	//男女の別なし
				PMTel_MsgPrintGmm(man,man->m_person,dat->msg[0]+rnd);
			}else{	//男女の言い分けアリ
				rnd *= 2;
				PMTel_MsgPrintGmmSex(man,man->m_person,dat->msg[0]+rnd,dat->msg[1]+rnd+1);
			}
		}
		break;
	default:
		if(!PMTel_MsgPrintWait(man)) return FALSE;
		MSGMAN_Delete(man->m_person);
		return TRUE;
	}
	++wk->seq;
	return FALSE;
}

